package cn.xwt.weidisk.controller.system;

import cn.xwt.weidisk.constant.ErrorCode;
import cn.xwt.weidisk.pojo.dao.FileDo;
import cn.xwt.weidisk.pojo.dao.RecycleDo;
import cn.xwt.weidisk.pojo.dao.RecycleFileDo;
import cn.xwt.weidisk.pojo.dto.*;
import cn.xwt.weidisk.service.FileService;
import cn.xwt.weidisk.service.RecycleService;
import cn.xwt.weidisk.service.UserService;
import cn.xwt.weidisk.util.CommonUtils;
import cn.xwt.weidisk.util.DiskUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;


/**
 * @author 薛慰涛
 * 网盘操作
 */
@RestController
@RequestMapping("/system/disk")
public class DiskController {

    Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    DiskUtils diskUtils;

    @Resource
    FileService fileService;

    @Resource
    UserService userService;

    @Resource
    RecycleService recycleService;

    /**
     * 获取文件上传链接
     *
     * @param fileDo  文件信息
     * @return resp
     */
    @PostMapping("/get-file-upload-url")
    public Resp getFileUploadUrl(@RequestBody FileDo fileDo) {
        try {
            String name = fileDo.getName();
            String suffix = name.substring(name.lastIndexOf("."));
            String uuid = UUID.randomUUID().toString().replace("-", "");
            fileDo.setKey(uuid + suffix);
            fileDo.setUid(CommonUtils.getUid());
        } catch (Exception e) {
            Resp resp = new Resp();
            resp.setCode("A0700");
            resp.setMsg("文件信息获取失败");
            return resp;
        }
        return fileService.getFileUploadUrl(fileDo);
    }

    /**
     * 保存图片文件缩略图
     * @param thumbnail 缩略信息
     * @return Resp
     */
    @PostMapping("/save-thumbnail")
    public Resp saveThumbnail(@RequestBody ThumbnailData thumbnail) {
        if (fileService.saveThumbnail(thumbnail)) {
            return Resp.success();
        } else {
            return Resp.serverError();
        }
    }

    /**
     * 获取下载链接
     *
     * @param name 文件名
     * @return Resp
     */
    @GetMapping("/get-file-download-url")
    public Resp getFileDownloadUrl(@RequestParam String name, @RequestParam String key) {
        String url = fileService.getFileDownloadUrl(name, key);
        if (url == null) {
            return Resp.serverError();
        } else {
            return new Resp("00000", "操作成功", url);
        }
    }


    /**
     * 获取文件列表
     * @return resp
     */
    @GetMapping("/get-all-list")
    public Resp getAllList(@RequestParam("path") String path) {
        List<FileDo> files = fileService.getAllList(CommonUtils.getUid(), path);
        if (null == files) {
            return new Resp("B0001", "服务器繁忙");
        } else {
            Resp resp = Resp.success();
            resp.setObject(files);
            return resp;
        }
    }


    /**
     * 新建文件夹
     *
     * @param folder  文件夹信息 name path
     * @return resp
     */
    @PostMapping("/new-folder")
    public Resp newFolder(@RequestBody FileDo folder) {
        folder.setUid(CommonUtils.getUid());
        folder.setType("folder");
        folder.setSize(0);
        if (fileService.insertFolder(folder)) {
            return Resp.success();
        } else {
            return new Resp("A0700", "文件夹已存在");
        }
    }

    /**
     * 重命名文件
     * @param renameFileData
     *          fid
     *          newName
     *          originalName
     *          path
     *          type
     * @return resp
     */
    @PutMapping("/rename")
    public Resp rename(@RequestBody RenameFileData renameFileData) {
        renameFileData.setUid(CommonUtils.getUid());
        if (fileService.updateName(renameFileData)) {
            return Resp.success();
        } else {
            return new Resp(ErrorCode.USER_UPLOAD_FILE_EXCEPTION.getCode(), "存在同名文件");
        }
    }

    /**
     * 删除文件
     * @param fileList 要删除的文件
     */
    @PutMapping("/delete-file")
    public void deleteFileList(@RequestBody List<FileDo> fileList) {
        Long uid = CommonUtils.getUid();
        // 保存选择的文件到recycle
        for (FileDo item : fileList) {
            // 添加记录到recycle中
            RecycleDo recycle = new RecycleDo();
            recycle.setUid(uid);
            recycle.setFid(item.getId());
            recycleService.insertRecycle(recycle);
            // 修改文件的rid
            Long rid = recycle.getId();
            item.setRid(rid);
            item.setUid(uid);
            fileService.deleteFile(item);
        }
    }

    /**
     * 获取文件夹树
     * @return FolderTree
     */
    @GetMapping("/get-folder-tree")
    public FolderTree getFolderTree() {
        return fileService.getFolderTree(CommonUtils.getUid());
    }

    /**
     * 移动文件
     * @param moveData 文件移动信息
     */
    @PostMapping("/move")
    public Resp moveFile(@RequestBody MoveData moveData) {
        return fileService.moveFile(moveData, CommonUtils.getUid());
    }

    /**
     * 获取图片列表
     * @return List<ImageData>
     */
    @GetMapping("/get-image-list")
    public List<ImageData> getImageList() {
        return fileService.getImageList(CommonUtils.getUid());
    }

    /**
     * 根据类型查询文件
     * @param type 类型
     * @return List<FileDo>
     */
    @GetMapping("/get-category-list")
    public List<FileDo> getCategoryList(@RequestParam String type) {
        String other = "other";
        Long uid = CommonUtils.getUid();
        if (type.equals(other)) {
            return fileService.selectOtherList(uid);
        } else {
            return fileService.selectListByType(uid, type);
        }
    }


    /**
     * 获取预览链接
     * @param key 文件key
     * @return 文件链接
     */
    @GetMapping("/get-preview-url")
    public String getPreviewUrl(@RequestParam("key") String key) {
        return fileService.getPreviewUrl(key);
    }

    /**
     * 通过用户id查询recycle列表
     * @return List<RecycleData>
     */
    @GetMapping("/get-recycle-list")
    public List<RecycleFileDo> getRecycleList() {
        return recycleService.selectRecycleList(CommonUtils.getUid());
    }

    /**
     * 还原回收站的文件
     * @param recycleFileList 要还原的文件
     * @return resp
     */
    @PutMapping("/revert-file")
    public Resp revertFile(@RequestBody List<RecycleFileDo> recycleFileList) {
        List<FileDo> failList = new LinkedList<>();
        Long uid = CommonUtils.getUid();
        // 如果容量不足
        if (!fileService.enableRecycle(recycleFileList, uid)) {
            return new Resp(ErrorCode.USER_OBJECT_STORAGE_CAPACITY_INSUFFICIENT.getCode(), "容量不足");
        }

        for (RecycleFileDo item : recycleFileList) {
            // 如果file中的文件还原成功就删除recycle表中的数据
            // 设置rid
            FileDo file = item.getFile();
            file.setRid(item.getId());
            file.setUid(uid);
            if (fileService.revertFile(file)) {
                recycleService.deleteRecycle(item.getId(), uid);
            } else {
                failList.add(item.getFile());
            }
        }

        if (failList.isEmpty()) {
            return Resp.success();
        } else {
            return new Resp(ErrorCode.USER_UPLOAD_FILE_EXCEPTION.getCode(), "存在重复文件");
        }
    }

    /**
     * 删除回收站中的文件
     * @param ridList 要删除的rid
     */
    @DeleteMapping("/delete-recycle")
    public void deleteRecycleFile(@RequestBody List<Long> ridList) {
        final Long uid = CommonUtils.getUid();
        recycleService.deleteRecycleList(ridList, uid);
        fileService.deleteFileListComplete(ridList, uid);
    }

    /**
     * 获取用户容量信息
     * @return capacityData
     */
    @GetMapping("/get-capacity")
    public CapacityData getCapacity() {
        Long uid = CommonUtils.getUid();
        Integer capacity = userService.getCapacity(uid);
        Integer used = fileService.getUsed(uid);
        Double progress = Double.parseDouble(String.format("%.2f", ((double)used / (double)capacity) * 100));
        return new CapacityData(capacity, used, progress);
    }

    /**
     * 判断用户cos空间是否充足
     * @param append 要添加的kb
     * @return resp
     */
    @GetMapping("/enable-upload")
    public Resp isEnough(@RequestParam("append") Long append) {
        return diskUtils.isEnough(append, CommonUtils.getUid()) ? Resp.success() : new Resp("A0604", "容量不足");
    }
 }